package de.justphil.tcg.tcgserver.game.mechanics.property.properties;

import java.util.List;
import org.slf4j.Logger;
import static de.justphil.tcg.tcgserver.commons.logging.TCGLogging.*;

import de.justphil.tcg.tcgserver.game.mechanics.config.Config;
import de.justphil.tcg.tcgserver.game.mechanics.event.Event;
import de.justphil.tcg.tcgserver.game.mechanics.game.BoardPosition;
import de.justphil.tcg.tcgserver.game.mechanics.game.Game;
import de.justphil.tcg.tcgserver.game.mechanics.monster.Monster;
import de.justphil.tcg.tcgserver.game.mechanics.monster.MonsterList;
import de.justphil.tcg.tcgserver.game.mechanics.property.Property;

public class DeathExplosion extends Property {

	private static final Logger log = gameLogger(DeathExplosion.class);

	public DeathExplosion(Game game) {

		super(game);
	}

	public static final int EXPLOSION_DAMAGE = 2;

	@Override
	protected List<Integer> getListeningEventTypes() {

		List<Integer> types = super.getListeningEventTypes();
		types.add(Event.EVENT_MONSTER_DIED);

		return types;
	}

	@Override
	protected MonsterList handleEvent(Event event) {

		int eventType = event.getType();

		switch (eventType) {
		case Event.EVENT_MONSTER_DIED:

			MonsterList monsters = new MonsterList();
			monsters.addAll(handleMonsterDied((Monster) event.getData()));
			return monsters;

		default:
			assert false;
			return null;
		}
	}

	private MonsterList handleMonsterDied(Monster monster) {

		MonsterList monsters = new MonsterList();
		if (getMonster().equals(monster)) {

			log.info("Exploding Monster ({}).", new Object[] {monster});

			BoardPosition position = getBoardInfo().getBoardPosition(monster);

			int player = position.getPlayer();
			int slot = position.getSlot();

			for (int surroundingPlayer = player - 1; surroundingPlayer <= player + 1; surroundingPlayer++) {

				if (surroundingPlayer >= 0
						&& surroundingPlayer < Config.NUM_PLAYERS) {

					for (int surroundingSlot = slot - 1; surroundingSlot <= slot + 1; surroundingSlot++) {

						if (surroundingSlot >= 0
								&& !(surroundingSlot == slot && surroundingPlayer == player)
								&& surroundingSlot < Config.NUM_SLOTS_PER_PLAYER) {

							Monster neighbour = getBoardInfo().getMonster(
									new BoardPosition(surroundingPlayer,
											surroundingSlot));

							if (neighbour != null) {

								monsters.add(neighbour);

								for (int i = 0; i < EXPLOSION_DAMAGE; i++) {
									provideProperty(neighbour, PROPERTY_DAMAGE);
								}
							}
						}
					}
				}
			}
		}
		return monsters;
	}

	@Override
	public int getType() {

		return PROPERTY_DEATH_EXPLOSION;
	}
}
